package com.acane.instagram.viewmodel

import android.content.Context
import android.net.Uri
import android.util.Log
import android.widget.Toast
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.acane.instagram.core.config.NotificationManager
import com.acane.instagram.core.config.WebSocketManager
import com.acane.instagram.core.model.Notification
import com.acane.instagram.core.model.UserInfo
import com.acane.instagram.core.model.network.datasource.MyRetrofitDatasource
import com.acane.instagram.feature.chat.CHAT_USER
import com.acane.instagram.feature.chat.ChatWebSocketClient
import com.acane.instagram.feature.common.SessionManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import okio.IOException

class ChatViewModel(
    savedStateHandle: SavedStateHandle
) : ViewModel(), ChatWebSocketClient.Listener {

    private val _isSending = MutableStateFlow(false)
    val isSending: StateFlow<Boolean> = _isSending

    private val userName: String = checkNotNull(savedStateHandle[CHAT_USER])
    val chatName = userName

    private val _receiver: UserInfo = UserInfo()

    var receiver: UserInfo = _receiver

    private val _messages = MutableStateFlow<List<Notification.ChatMessage>>(emptyList())
    val messages: MutableStateFlow<List<Notification.ChatMessage>> = _messages

    private val _isConnected = mutableStateOf(false)


    init {
        WebSocketManager.addListener(this) // 注册全局监听
        loadReceiver(chatName)
        loadChatHistory(SessionManager.currentUser?.userName!!, chatName)

        // 首次连接检查
        checkInitialConnection()
    }

    private fun checkInitialConnection() {
        viewModelScope.launch {
            if (WebSocketManager.isConnected.not()) {
                SessionManager._sessionId?.let {
                    WebSocketManager.connect(it)
                }
            }
        }
    }

    private fun loadReceiver(chatName: String) {
        viewModelScope.launch {
            receiver = MyRetrofitDatasource.getUserByUserName(chatName).data!!
        }
    }

    // 修改 updateMessages 方法，基于消息 ID 去重
    private fun updateMessages(newMessage: Notification.ChatMessage) {
        val updatedMessages = mutableListOf<Notification.ChatMessage>().apply {
            add(newMessage)
            addAll(_messages.value)
        }
        _messages.value = updatedMessages.sortedByDescending { it.timestamp }
    }
    // ChatViewModel.kt 修改消息处理逻辑
    override fun onMessageReceived(message: Notification) {
        if (message is Notification.ChatMessage) {
            viewModelScope.launch(Dispatchers.Main) {
                updateMessages(message)
            }
        } else {
            // 非聊天消息转交给通知管理器
            NotificationManager.handleNotification(message)
        }
    }


    override fun onConnected() {
        _isConnected.value = true
    }

    override fun onClosed(code: Int, reason: String) {
        _isConnected.value = false
        println("WebSocket closed: $code, $reason")
    }

    override fun onFailure(t: Throwable, response: Response?) {
        _isConnected.value = false
        println("WebSocket connection failed: ${t.message}")
    }


    private fun Uri.toMultipartBodyPart(
        context: Context,
        partName: String,
        fileName: String? // 允许传递null
    ): MultipartBody.Part {
        return context.contentResolver.openInputStream(this)?.use { stream ->
            // 获取实际MIME类型
            val mimeType = context.contentResolver.getType(this) ?: "application/octet-stream"
            val requestBody = stream.readBytes().toRequestBody(mimeType.toMediaType())

            // 如果fileName为null，由后端决定文件名
            MultipartBody.Part.createFormData(
                partName,
                fileName ?: "", // 空文件名让后端处理
                requestBody
            )
        } ?: throw IOException("无法读取文件")
    }

    fun sendMessage(toName: String, message: String, fromName: String, context: Context) {
        viewModelScope.launch {
            try {
                val hasSensitive = MyRetrofitDatasource.checkSensitive(message).data
                if (hasSensitive == true) {
                    // 弹出提示：消息包含敏感词，请修改
                    Toast.makeText(context, "消息包含敏感词，请修改", Toast.LENGTH_SHORT).show()
                    return@launch
                }
                // 在需要发送通知的地方调用
                val notification = Notification.ChatMessage(
                    id = "",
                    timestamp = null,
                    content = message,
                    sender = fromName,
                    receiver = toName,
                    mediaType = "text"
                )
                WebSocketManager.sendNotification(notification)
                //WebSocketManager.sendMessage(toName, message, fromName)
                // 仅发送，不本地添加
                //chatWebSocketClient.sendMessage(toName, message, fromName)
            } catch (e: Exception) {
                Log.e("ChatViewModel", "发送失败: ${e.message}")
            }
        }
    }

    suspend fun sendMediaMessage(
        toName: String,
        fileUri: Uri,
        fromName: String,
        context: Context
    ): Boolean = withContext(Dispatchers.IO)  {
            try {

        // 创建并发送消息
        val filePart = fileUri.toMultipartBodyPart(
                        context = context,
                        partName = "file",
                        fileName = null
                    )
                    val response = MyRetrofitDatasource.uploadMedia(
                        file = filePart
                    )
        val mediaUrl = response.data ?: return@withContext false

                    val type = if (mediaUrl.endsWith(".jpg") == true) "image" else "video"
                    Log.d("ChatViewModel", "文件类型：$type")


                // 在需要发送通知的地方调用
                val notification = Notification.ChatMessage(
                    id = "",
                    timestamp = null,
                    content = mediaUrl,
                    sender = fromName,
                    receiver = toName,
                    mediaType = type
                )
                WebSocketManager.sendNotification(notification)

                Log.d("ChatViewModel", "上传媒体成功 URL: $mediaUrl")
        Log.d("ChatViewModel", "创建媒体消息: ${notification}")
        true
    } catch (e: Exception) {
        false
    }

}
    fun loadChatHistory(sender: String, receiver: String) {
        viewModelScope.launch {
            try {
                // 从数据库获取聊天记录
                val chatHistory = MyRetrofitDatasource.getChatHistory(sender, receiver)
                Log.d("ChatViewModel", "-----------加载聊天记录：\n$chatHistory")
                _messages.value = chatHistory.data ?: emptyList()
            } catch (e: Exception) {
                // Handle error
                println("Failed to load chat history: ${e.message}")
            }
        }
    }

    override fun onCleared() {
        super.onCleared()
        WebSocketManager.removeListener(this) // 重要！防止内存泄漏
    }
}
